---
title: .autoDispose
---

:::caution
The content of this page may be outdated.  
It will be updated in the future, but for now you may want to refer to the content
in the top of the sidebar instead (introduction/essentials/case-studies/...)
:::

A common use case is to destroy the state of a provider
when it is no-longer used.

There are multiple reasons for doing so, such as:

- When using Firebase, to close the connection and avoid unnecessary cost.
- To reset the state when the user leaves a screen and re-enters it.

Providers come with built-in support for this use case, through the `.autoDispose`
modifier.

## Usage

To tell Riverpod to destroy the state of a provider when it is no longer used,
simply append `.autoDispose` to your provider:

```dart
final userProvider = StreamProvider.autoDispose<User>((ref) {

});
```

That's it. Now, the state of `userProvider` will automatically be destroyed
when it is no longer used.

Note how the generic parameters are passed after `autoDispose` instead of before –
`autoDispose` is not a named constructor.

:::note
You can combine `.autoDispose` with other modifiers if you need to:

```dart
final userProvider = StreamProvider.autoDispose.family<User, String>((ref, id) {

});
```

:::

### ref.keepAlive

Marking a provider with `autoDispose` also adds an extra method on `ref`: `keepAlive`.

The `keepAlive` function is used to tell Riverpod that the state of the provider
should be preserved even if no longer listened to.

A use-case would be to set this flag to `true` after an HTTP request has
completed:

```dart
final myProvider = FutureProvider.autoDispose((ref) async {
  final response = await httpClient.get(...);
  ref.keepAlive();
  return response;
});
```

This way, if the request fails and the user leaves the screen then re-enters
it, then the request will be performed again.
But if the request completed successfully, the state will be preserved
and re-entering the screen will not trigger a new request.

:::info
In version 1.0.x, the equivalent of `keepAlive` is the property called `maintainState`.
:::

## Example: Canceling HTTP requests when no longer used

The `autoDispose` modifier could be combined with [FutureProvider] and `ref.onDispose`
to easily cancel HTTP requests when they are no longer needed.

The goal is:

- Start an HTTP request when the user enters a screen
- if the user leaves the screen before the request completed, cancel the HTTP request
- if the request succeeded, leaving and re-entering the screen does not start a new request

In code, this would be:

```dart
final myProvider = FutureProvider.autoDispose((ref) async {
  // An object from package:dio that allows cancelling http requests
  final cancelToken = CancelToken();
  // When the provider is destroyed, cancel the http request
  ref.onDispose(() => cancelToken.cancel());

  // Fetch our data and pass our `cancelToken` for cancellation to work
  final response = await dio.get('path', cancelToken: cancelToken);
  // If the request completed successfully, keep the state
  ref.keepAlive();
  return response;
});
```

## The argument type 'AutoDisposeProvider' can't be assigned to the parameter type 'AlwaysAliveProviderBase'

When using `.autoDispose`, you may find yourself in a situation where your
application does not compile with an error similar to:

> The argument type 'AutoDisposeProvider' can't be assigned to the parameter
> type 'AlwaysAliveProviderBase'

Don't worry! This error is voluntary. It happens because you most likely
have a bug:

You tried to listen to a provider marked with `.autoDispose` in a provider that
is **not** marked with `.autoDispose`, such as:

```dart
final firstProvider = Provider.autoDispose((ref) => 0);

final secondProvider = Provider((ref) {
  // The argument type 'AutoDisposeProvider<int>' can't be assigned to the
  // parameter type 'AlwaysAliveProviderBase<Object, Null>'
  ref.watch(firstProvider);
});
```

This is undesired, as it would cause `firstProvider` to never be disposed.

To fix this, consider marking `secondProvider` with `.autoDispose` too:

```dart
final firstProvider = Provider.autoDispose((ref) => 0);

final secondProvider = Provider.autoDispose((ref) {
  ref.watch(firstProvider);
});
```

[futureprovider]: https://pub.dev/documentation/hooks_riverpod/latest/hooks_riverpod/FutureProvider-class.html
